package api

import (
	"context"
	"github.com/google/wire"
	"github.com/hashicorp/consul/api"
	"jmicro/app/jshop/api/config"
	v1 "jmicro/app/jshop/api/internal/controller/v1"
	"jmicro/app/pkg/options"
	gapp "jmicro/jmicro/app"
	"jmicro/jmicro/registry"
	"jmicro/jmicro/registry/consul"
	"jmicro/jmicro/server/restserver"
	"jmicro/pkg/app"
	"jmicro/pkg/log"
	"jmicro/pkg/storage"
)

var ProviderSet = wire.NewSet(NewRegistrar, NewAPIApp, NewAPIHTTPServer, v1.NewUserController)

func NewApp(basename string) *app.App {
	cfg := config.New()
	appl := app.NewApp("api",
		"jmicro",
		app.WithOptions(cfg),
		app.WithRunFunc(run(cfg)),
		//不读配置 使用命令行参数时使用
		//app.WithNoConfig(),
	)
	return appl
}
func NewRegistrar(registry *options.RegistryOptions) registry.Registrar {
	c := api.DefaultConfig()
	c.Address = registry.Address
	c.Scheme = registry.Scheme
	cli, err := api.NewClient(c)
	if err != nil {
		panic(err)
	}
	r := consul.New(cli, consul.WithHealthCheck(true))
	return r
}
func NewAPIApp(redisOptions *options.RedisOptions, serverOptions *options.ServerOptions,
	options2 *log.Options, registry registry.Registrar, server *restserver.Server) (*gapp.App, error) {
	//初始化log
	log.Init(options2)
	defer log.Flush()
	//服务注册
	//register := NewRegistrar(cfg.Registry)
	//连接redis
	redisConfig := &storage.Config{
		Host:                  redisOptions.Host,
		Port:                  redisOptions.Port,
		Addrs:                 redisOptions.Addrs,
		MasterName:            redisOptions.MasterName,
		Username:              redisOptions.Username,
		Password:              redisOptions.Password,
		Database:              redisOptions.Database,
		MaxIdle:               redisOptions.MaxIdle,
		MaxActive:             redisOptions.MaxActive,
		Timeout:               redisOptions.Timeout,
		EnableCluster:         redisOptions.EnableCluster,
		UseSSL:                redisOptions.UseSSL,
		SSLInsecureSkipVerify: redisOptions.SSLInsecureSkipVerify,
		EnableTracing:         redisOptions.EnableTracing,
	}
	go storage.ConnectToRedis(context.Background(), redisConfig)
	//生成http服务
	//restServer, err := NewAPIHTTPServer(cfg)
	//if err != nil {
	//	return nil, err
	//}
	return gapp.New(
		gapp.WithName(serverOptions.Name),
		gapp.WithRestServer(server),
		gapp.WithRegistrar(registry),
	), nil
}

// controller(参数校验) ->service(具体的业务逻辑)->(数据库的接口)
func run(cfg *config.Config) app.RunFunc {
	return func(baseName string) error {
		//apiApp, err := NewAPIApp(cfg)
		apiApp, err := initApp(cfg.Mysql, cfg.Telemetry, cfg.Jwt, cfg.Sms, cfg.Registry, cfg.Redis, cfg.Server, cfg.Log)
		if err != nil {
			return err
		}
		//启动
		if err = apiApp.Run(); err != nil {
			log.Errorf("run api app error: %s", err)
		}
		return nil
	}
}
